package cn.edu.lsnu.mbti.service.impl;

import cn.edu.lsnu.mbti.entity.Region;
import cn.edu.lsnu.mbti.entity.University;
import cn.edu.lsnu.mbti.entity.User;
import cn.edu.lsnu.mbti.exception.CustomerException;
import cn.edu.lsnu.mbti.mapper.RegionMapper;
import cn.edu.lsnu.mbti.service.RegionService;
import cn.edu.lsnu.mbti.service.UniversityService;
import cn.edu.lsnu.mbti.service.UserService;
import cn.edu.lsnu.mbti.util.RedisUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements RegionService {

    public static final String regionKey = "MBTI:REGION:ALL";
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RegionMapper regionMapper;
    @Resource
    @Lazy
    private UniversityService universityService;
    @Resource
    @Lazy
    private UserService userService;


    /**
     * 根据id删除
     * @param regionId
     * @return
     */
    @Override
    @Transactional
    public String deleteById(String regionId) {
        //根据id查询学校列表
        LambdaQueryWrapper<University> universityWrapper = new LambdaQueryWrapper<>();
        universityWrapper.eq(University::getRegionId,regionId);
        List<University> universityList = Optional.ofNullable(universityService.list(universityWrapper))
                                                  .orElse(new ArrayList<>());

        try {
            //将学校的region_id置为空
            if (universityList.size() > 0){
                List<University> collect = universityList.stream().map(university -> {
                    university.setRegionId("");
                    return university;
                }).collect(Collectors.toList());
                universityService.updateBatchById(collect);
            }

            //根据id查询用户列表
            LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(User::getRegionId,regionId);
            List<User> userList = Optional.ofNullable(userService.list(userWrapper))
                    .orElse(new ArrayList<>());
            //将用户的region_id置为空
            if (userList.size() > 0){
                List<User> collect = userList.stream().map(user -> {
                    user.setRegionId("");
                    return user;
                }).collect(Collectors.toList());
                userService.updateBatchById(collect);
            }

            //删除该地区
            regionMapper.deleteById(regionId);
        } catch (Exception e) {
            throw new CustomerException("删除失败，请稍后重试");
        }

        return "删除成功";
    }

    /**
     * 新增或修改地区信息
     * @param region
     * @return
     */
    @Override
    @Transactional
    public String saveRegion(Region region) {
        //获取id
        String regionId = region.getId();

        //判断id是否为空
        try {
            if (StrUtil.isBlank(regionId)){
                //为空，新增
                regionMapper.insert(region);
            }
            //修改
            regionMapper.updateById(region);
        } catch (Exception e) {
            throw new CustomerException("保存失败，请稍后重试");
        }

        return "保存成功";
    }

    /**
     * 根据名称分页查询地区
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page<Region> queryPageRegionList(int pageNum, int pageSize, String name) {
        //构造查询条件
        LambdaQueryWrapper<Region> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Region::getName,name);

        //分页查询条件
        Page<Region> regionPage = new Page<>(pageNum, pageSize);

        //分页查询
        regionPage = this.page(regionPage,wrapper);

        return regionPage;
    }

    /**
     * 查询地区集合
     * redis做缓存
     * @return
     */
    @Override
    public List<Region> regionList() {
        List<Region> regionList;
        //根据key查询redis中是否缓存了数据
        String jsonStr = (String) redisUtil.get(regionKey);
        if (StrUtil.isNotBlank(jsonStr)){
            //不为空，redis中有改key的数据，直接转成对象返回
            regionList = JSONUtil.toBean(jsonStr, new TypeReference<List<Region>>() {
            }, true);
            return regionList;
        }
        regionList = this.list();
        redisUtil.set(regionKey,JSONUtil.toJsonStr(regionList),604800);
        return regionList;
    }

}
